package com.cg;

import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.atomic.AtomicReference;

/**
 * completableFuture使用自定义线程池
 */
public class CompleteFutureTest06 {

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        long startTime = System.currentTimeMillis();
        AtomicReference<String> a = new AtomicReference<>();
        AtomicReference<String> d = new AtomicReference<>();
        AtomicReference<String> g = new AtomicReference<>();

        ThreadPoolTaskExecutor threadPoolTaskExecutor = selfThreadPoolExecutor();
        CompletableFuture<Void> voidCompletableFuture = CompletableFuture.supplyAsync(() -> {
                    System.out.println(Thread.currentThread().getName());
                    try {
                        Thread.sleep(2500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    return new User1();
                }, threadPoolTaskExecutor)
                .thenAccept(item -> {
                    a.set(item.getA());
                });

        CompletableFuture<Void> voidCompletableFuture1 = CompletableFuture.supplyAsync(() -> {
                    System.out.println(Thread.currentThread().getName());
                    try {
                        Thread.sleep(1500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    return new User2();
                }, threadPoolTaskExecutor)
                .thenAccept(item -> {
                    d.set(item.getD());
                });

        CompletableFuture<Void> voidCompletableFuture2 = CompletableFuture.supplyAsync(() -> {
                    System.out.println(Thread.currentThread().getName());
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    return new User3();
                }, threadPoolTaskExecutor)
                .thenAccept(item -> {
                    g.set(item.getG());
                });

        voidCompletableFuture.join();
        voidCompletableFuture1.join();
        voidCompletableFuture2.join();

        System.out.println(a.get());
        System.out.println(d.get());
        System.out.println(g.get());
        System.out.println(System.currentTimeMillis() - startTime);
    }

    public static ThreadPoolTaskExecutor selfThreadPoolExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        //设置线程名称
        executor.setThreadNamePrefix("completableFuture--pool");
        //设置最大线程数
        executor.setMaxPoolSize(Runtime.getRuntime().availableProcessors());
        //设置核心线程数
        executor.setCorePoolSize(Runtime.getRuntime().availableProcessors());
        //设置线程空闲时间，默认60
        executor.setKeepAliveSeconds(60);
        //设置队列容量
        executor.setQueueCapacity(1000);

        // 设置拒绝策略
        executor.setRejectedExecutionHandler(new RejectedExecutionHandler() {
            @Override
            public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                // .....任务过多时，存入数据库，定时执行，还是...
            }
        });
        // 使用预定义的异常处理类
        // executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.initialize();
        return executor;
    }

}
